package com.ruoyi.web.controller.monitor

import com.ruoyi.common.annotation.Log
import com.ruoyi.common.constant.CacheConstants
import com.ruoyi.common.core.controller.BaseController
import com.ruoyi.common.core.domain.AjaxResult
import com.ruoyi.common.core.domain.model.LoginUser
import com.ruoyi.common.core.page.TableDataInfo
import com.ruoyi.common.core.redis.RedisCache
import com.ruoyi.common.enums.BusinessType
import com.ruoyi.system.domain.SysUserOnline
import com.ruoyi.system.service.ISysUserOnlineService
import org.apache.commons.lang3.StringUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.*
import java.util.*

/**
 * 在线用户监控
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/monitor/online")
open class SysUserOnlineController : BaseController() {

    @Autowired
    private lateinit var userOnlineService: ISysUserOnlineService

    @Autowired
    private lateinit var redisCache: RedisCache

    @PreAuthorize("@ss.hasPermi('monitor:online:list')")
    @GetMapping("/list")
    open fun list(ipaddr: String?, userName: String?): TableDataInfo {
        val keys: MutableSet<String> = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*")
        val userOnlineList = mutableListOf<SysUserOnline?>()
        for (key in keys) {
            val user: LoginUser? = redisCache.getCacheObject(key)
            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
                user?.let { it ->
                    userOnlineService.selectOnlineByInfo(ipaddr, userName, it)?.let { userOnlineList.add(it) }
                }
            } else if (StringUtils.isNotEmpty(ipaddr)) {
                user?.let { it -> userOnlineService.selectOnlineByIpaddr(ipaddr, it)?.let { userOnlineList.add(it) } }
            } else if (StringUtils.isNotEmpty(userName) && com.ruoyi.common.utils.MyStringUtils.isNotNull(user?.user)) {
                user?.let { it ->
                    userOnlineService.selectOnlineByUserName(userName, it)?.let { userOnlineList.add(it) }
                }
            } else {
                user?.let { it -> userOnlineService.loginUserToUserOnline(it)?.let { userOnlineList.add(it) } }
            }
        }
        userOnlineList.reverse()
        userOnlineList.removeAll(Collections.singleton(null))
        return getDataTable(userOnlineList)
    }

    /**
     * 强退用户
     */
    @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
    @Log(title = "在线用户", businessType = BusinessType.FORCE)
    @DeleteMapping("/{tokenId}")
    open fun forceLogout(@PathVariable tokenId: String): AjaxResult {
        redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId)
        return success()
    }
}
